                                                                     
                                                                     
                                                                     
                                             
-- Credits to Interview for part of the list function!

local GENERIC_TARGET_REGEXP = "target=[^,%]]+";
-- "target=[%P]+"

SARFFIX2_MACROTARGETREPLACECMD = {
	"/macrotargetreplacement";
	"/macrotargetreplacer";
	"/macrotargetreplace";
	"/macrotr";
	"/mtr";
};


function SarfFix2:Macro_GetPersonalMacroNameList()
	local l = {};
	local numglobal,numperchar = GetNumMacros();

	local name, texture, macrobody, islocal 
	if numglobal == nil then numglobal = 0 end
	if numperchar == nil then numperchar = 0 end

	local maxMacros = 18;

	for i=1,numperchar do 
		name, _, _, islocal= GetMacroInfo(i+maxMacros)
		table.insert(l, name)
	end
	return l;
end

function SarfFix2:Macro_TargetReplace(newTarget, oldTarget)
	for k, v in pairs(SarfFix2:Macro_GetPersonalMacroNameList()) do
		SarfFix2:Macro_TargetReplaceInMacro(v, newTarget, oldTarget);
	end
end

function SarfFix2:Macro_TargetReplaceInMacro(macroName, newTarget, oldTarget)
	local macroBody = SarfFix2:Macro_GetMacroBody(macroName);
	if ( macroBody ) then
		local newMacroBody = SarfFix2:Macro_TargetReplaceInText(macroBody, newTarget, oldTarget);
		if ( newMacroBody ) and ( macroBody ~= newMacroBody ) then
			SarfFix2:Macro_ReplaceMacroBody(macroName, newMacroBody);
		end
	end
end

function SarfFix2:Macro_GetMacroBody(macroName, perCharacter)
	if ( not perCharacter ) then
		perCharacter = 0;
	end
	local index = GetMacroIndexByName(macroName);
	if ( not index ) then
		return nil;
	end
	local name, iconTexture, body, loc = GetMacroInfo(index);
	return body;
end


function SarfFix2:Macro_TargetReplaceInText(macroBody, newTarget, oldTarget)
	local findStr = nil;
	local replaceStr = nil;
	if ( oldTarget ) then
		findStr = "target="..oldTarget;
		replaceStr = "target="..newTarget;
		return string.gsub(macroBody, findStr, replaceStr);
	else
		findStr = GENERIC_TARGET_REGEXP;
		replaceStr = "target="..newTarget;
		return string.gsub(macroBody, findStr, replaceStr);
	end
end

function SarfFix2:Macro_ReplaceMacroBody(macroName, macroBody, perCharacter)
	if ( not perCharacter ) then
		perCharacter = 0;
	end
	local index = GetMacroIndexByName(macroName);
	if ( not index ) then
		return false;
	end
	local name, iconTexture, body, loc = GetMacroInfo(index);
	body = macroBody;
	EditMacro(index, name, icon, body, loc, perCharacter);
	return true;
end


function SarfFix2:Macro_Setup()
	local slashName = "MACROTARGETREPLACECMD";
	for k,v in pairs(getglobal("SARFFIX2_"..slashName)) do
		setglobal("SLASH_"..slashName..k, v);
	end
	SlashCmdList[slashName] = function(str) return SarfFix2:Macro_TargetReplaceCmd(str) end;
end

function SarfFix2:Macro_SplitArgs(pStr)
	local arg = {};
	local index;
	local str = pStr;
	
	index = string.find(str, " ");
	while ( index ~= nil ) do
		table.insert(arg, string.sub(str, 1, index));
		str = string.sub(str, index+1);
		index = string.find(str, " ");
	end
	if ( string.len(str) > 0 ) then
		table.insert(arg, str);
	end
	return arg;
end

function SarfFix2:Macro_TargetReplaceCmd(str)
	if ( InCombatLockdown() ) then
		-- TODO: Queue macro replacement?
		SarfFix2:PrintError("MacroTargetReplace: Currently in combat. Macros can not be changed in combat.");
		SarfFix2:PrintError("In other words, 'I'm sorry Dave, but I can't let you do that.'");
		return;
	end
	
	if ( MacroFrame ) and ( MacroFrame:IsVisible() ) then
		-- TODO: Queue macro replacement?
		SarfFix2:PrintError("The Blizzard macro window is shown. Because of how the Blizzard macro window works, changing macros while it is visible is a pain in the rear.");
		SarfFix2:PrintError("In other words, 'I'm sorry Dave, but I can't let you do that.' Close the macro window and try again");
		return;
	end
	
	local cmdArg = {};
	for word in string.gmatch(str, "%w+") do table.insert(cmdArg, word); end
	if ( cmdArg[1] ~= nil ) then
		local replaceIndex = 1;
		local index = 0;
		for k, v in pairs(cmdArg) do
			index = GetMacroIndexByName(v);
			if ( index ) and ( index ~= 0 ) then
				replaceIndex = k+1;
			else
				break;
			end
		end
		if ( cmdArg[replaceIndex+1] ) then
			SarfFix2:Print("Replacing macro targets corresponding to "..cmdArg[replaceIndex+1].." with "..cmdArg[replaceIndex]);
		else
			SarfFix2:Print("Replacing macro targets to "..cmdArg[replaceIndex]);
		end
		if ( replaceIndex > 1 ) then
			SarfFix2:Print("Replacing specified macros only");
			for index = 1, (replaceIndex-1) do
				SarfFix2:Macro_TargetReplaceInMacro(cmdArg[index], cmdArg[replaceIndex], cmdArg[replaceIndex+1]);
			end
		else
			SarfFix2:Macro_TargetReplace(cmdArg[replaceIndex], cmdArg[replaceIndex+1]);
		end
	else
		SarfFix2:PrintError("Not enough parameters. Usage: /mrt [MacroName[, MacroName[, MacroName]]]<new macro target> [old macro target]");
	end
end

SarfFix2:Macro_Setup();
